
/*********************************  COPYRIGHT 2022 --------  *********  BEGIN OF FILE  ********************************/

/**********************************************************************
* @file           : bldc_sixstep.c
* @author         : --
* @version        : --
* @date           : 2022-03-07
* @brief          : bldc_sixstep program body
* @Description    : --
**********************************************************************/

/*-- Includes -------------------------------------------------------*/
#include "bldc_sixstep.h"
#include "pwm.h"
#include "systick.h"
#include "err.h"
#include "padc.h"
#include "global.h"
#include <string.h>
#include <stdlib.h>
#include "heat.h"


/*-- Private typedef ------------------------------------------------*/
/*-- Private define -------------------------------------------------*/

//-----------------------------------------//
#define	BLDC_SIXSTEP_LIN1_GPIO   GPIOB
#define	BLDC_SIXSTEP_LIN1_PIN   GPIO_Pin_12
#define	BLDC_SIXSTEP_LIN1_CLK   RCC_APB2Periph_GPIOB

#define	BLDC_SIXSTEP_LIN2_GPIO   GPIOB
#define	BLDC_SIXSTEP_LIN2_PIN   GPIO_Pin_11
#define	BLDC_SIXSTEP_LIN2_CLK   RCC_APB2Periph_GPIOB

#define	BLDC_SIXSTEP_LIN3_GPIO   GPIOB
#define	BLDC_SIXSTEP_LIN3_PIN   GPIO_Pin_10
#define	BLDC_SIXSTEP_LIN3_CLK   RCC_APB2Periph_GPIOB

#define	BLDC_SIXSTEP_HALLU_GPIO   GPIOA
#define	BLDC_SIXSTEP_HALLU_PIN   GPIO_Pin_7
#define	BLDC_SIXSTEP_HALLU_CLK   RCC_APB2Periph_GPIOA
#define	BLDC_SIXSTEP_HALLU_PORT_SOURCE     GPIO_PortSourceGPIOA
#define	BLDC_SIXSTEP_HALLU_PIN_SOURCE      GPIO_PinSource7
#define	BLDC_SIXSTEP_HALLU_LINE            EXTI_Line7
#define	BLDC_SIXSTEP_HALLU_IRQn            EXTI9_5_IRQn
#define	BLDC_SIXSTEP_HALLU_IRQHandler      EXTI9_5_IRQHandler

#define	BLDC_SIXSTEP_HALLV_GPIO   GPIOC
#define	BLDC_SIXSTEP_HALLV_PIN   GPIO_Pin_4
#define	BLDC_SIXSTEP_HALLV_CLK   RCC_APB2Periph_GPIOC
#define	BLDC_SIXSTEP_HALLV_PORT_SOURCE     GPIO_PortSourceGPIOC
#define	BLDC_SIXSTEP_HALLV_PIN_SOURCE      GPIO_PinSource4
#define	BLDC_SIXSTEP_HALLV_LINE            EXTI_Line4
#define	BLDC_SIXSTEP_HALLV_IRQn            EXTI4_IRQn
#define	BLDC_SIXSTEP_HALLV_IRQHandler      EXTI4_IRQHandler

#define	BLDC_SIXSTEP_HALLW_GPIO   GPIOA
#define	BLDC_SIXSTEP_HALLW_PIN   GPIO_Pin_6
#define	BLDC_SIXSTEP_HALLW_CLK   RCC_APB2Periph_GPIOA
#define	BLDC_SIXSTEP_HALLW_PORT_SOURCE     GPIO_PortSourceGPIOA
#define	BLDC_SIXSTEP_HALLW_PIN_SOURCE      GPIO_PinSource6
#define	BLDC_SIXSTEP_HALLW_LINE            EXTI_Line6
#define	BLDC_SIXSTEP_HALLW_IRQn            EXTI9_5_IRQn
#define	BLDC_SIXSTEP_HALLW_IRQHandler      EXTI9_5_IRQHandler

#define	BLDC_SIXSTEP_FAULT_GPIO   GPIOB
#define	BLDC_SIXSTEP_FAULT_PIN   GPIO_Pin_0
#define	BLDC_SIXSTEP_FAULT_CLK   RCC_APB2Periph_GPIOB
#define	BLDC_SIXSTEP_FAULT_PORT_SOURCE     GPIO_PortSourceGPIOB
#define	BLDC_SIXSTEP_FAULT_PIN_SOURCE      GPIO_PinSource0
#define	BLDC_SIXSTEP_FAULT_LINE            EXTI_Line0
#define	BLDC_SIXSTEP_FAULT_IRQn            EXTI0_IRQn
#define	BLDC_SIXSTEP_FAULT_IRQHandler      EXTI0_IRQHandler

//-----------------------------------------//
// 计算速度的频率BLDC_FREQ是BLDC_SPEED_BUFF_CNT * BLDC_SPEED_PERIOD
// 速度显示的分辨率为60 / BLDC_FREQ * BLDC_ENCODER_ONE_CYCLE_NUM
#define	BLDC_SIXSTEP_ENCODER_ONE_CYCLE_NUM   24//18//36    // 转一圈编码器输出脉冲数
#define	BLDC_SIXSTEP_SPEED_BUFF_CNT   10    // 保存速度缓存
#define	BLDC_SIXSTEP_SPEED_CALA_CNT   (BLDC_SIXSTEP_SPEED_BUFF_CNT + 1)    // 保存速度缓存
#define	BLDC_SIXSTEP_SPEED_PERIOD   100000   // 保存速度的时间间隔
#define	BLDC_SIXSTEP_SPEED_SAMPLE_TIME   (BLDC_SIXSTEP_SPEED_BUFF_CNT * BLDC_SIXSTEP_SPEED_PERIOD)   // 速度采样时间
// 一分钟内速度采样的次数
#define	BLDC_SIXSTEP_SPEED_SAMPLE_CNT  (60000000 / BLDC_SIXSTEP_SPEED_SAMPLE_TIME)

#define	BLDC_SIXSTEP_CURRENT_TIME   200000 

#define BLDC_SIXSTEP_PID_P   20
#define BLDC_SIXSTEP_PID_I   100
#define BLDC_SIXSTEP_PID_D   60

#define BLDC_SIXSTEP_SPEED_BIAS   15

#define BLDC_SIXSTEP_INIT_DUTY   180//200			//无刷电机初始PWM宽度
#define BLDC_SIXSTEP_MAX_DUTY   (PWM_BLDC_PERIOD - 10)



/*-- Private macro --------------------------------------------------*/
/*-- Private variables ----------------------------------------------*/

//-----------------------------------------//
u32 BLDC_SIXSTEP_SpeedCnt;
u32 BLDC_SIXSTEP_SpeedCnt_Buff[BLDC_SIXSTEP_SPEED_CALA_CNT];
s64 BLDC_SIXSTEP_SpeedTime_Buff[BLDC_SIXSTEP_SPEED_CALA_CNT];

s16 BLDC_SIXSTEP_OriginalDuty;	//原始值
s16 BLDC_SIXSTEP_Duty;					//无刷电机PWM脉宽
s16 BLDC_SIXSTEP_ExpectDuty;		//目标值
u32 BLDC_SIXSTEP_HallCnt;				//霍尔计数
u16 BLDC_SIXSTEP_Direction;				//方向
s16 BLDC_SIXSTEP_RealSpeed;					//实际速度
s16 BLDC_SIXSTEP_ExpectSpeed;			//目标速度
s16 BLDC_SIXSTEP_MaxSpeed;				//最大速度
u8 BLDC_SIXSTEP_RunFlag;					//运行标志位
u8 BLDC_SIXSTEP_HallUpdateFlag;
u8 BLDC_SIXSTEP_RunCnt;

s64 BLDC_SIXSTEP_RunTime;
s64 BLDC_SIXSTEP_PIDTime;
s64 BLDC_SIXSTEP_SpeedTime;
s64 BLDC_SIXSTEP_ErrDetectTime;

s16 BLDC_SIXSTEP_ErrLast;
s32 BLDC_SIXSTEP_ErrSum;

s64 BLDC_SIXSTEP_CurrentTime;

u8 BLDC_SIXSTEP_SpeedReachFlag;
u8 BLDC_SIXSTEP_IntLastStatus;



/*-- Private function prototypes ------------------------------------*/

//-----------------------------------------//



/*-- Private functions ----------------------------------------------*/

/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
static void BLDC_SIXSTEP_CHN_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	//使能相关GPIO口时钟
	RCC_APB2PeriphClockCmd(BLDC_SIXSTEP_LIN1_CLK | BLDC_SIXSTEP_LIN2_CLK | BLDC_SIXSTEP_LIN3_CLK, ENABLE);
		
	//配置输出引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;		

	GPIO_InitStructure.GPIO_Pin = BLDC_SIXSTEP_LIN1_PIN;
	GPIO_Init(BLDC_SIXSTEP_LIN1_GPIO, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = BLDC_SIXSTEP_LIN2_PIN;
	GPIO_Init(BLDC_SIXSTEP_LIN2_GPIO, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = BLDC_SIXSTEP_LIN3_PIN;
	GPIO_Init(BLDC_SIXSTEP_LIN3_GPIO, &GPIO_InitStructure);	
	
	GPIO_SetBits(BLDC_SIXSTEP_LIN1_GPIO, BLDC_SIXSTEP_LIN1_PIN);
	GPIO_SetBits(BLDC_SIXSTEP_LIN2_GPIO, BLDC_SIXSTEP_LIN2_PIN);
	GPIO_SetBits(BLDC_SIXSTEP_LIN3_GPIO, BLDC_SIXSTEP_LIN3_PIN);
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
static void BLDC_SIXSTEP_HALL_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;

	//使能相关GPIO口时钟
	RCC_APB2PeriphClockCmd(BLDC_SIXSTEP_HALLU_CLK | BLDC_SIXSTEP_HALLV_CLK | BLDC_SIXSTEP_HALLW_CLK | RCC_APB2Periph_AFIO, ENABLE);
		
	//配置输入引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;		

	GPIO_InitStructure.GPIO_Pin = BLDC_SIXSTEP_HALLU_PIN;
	GPIO_Init(BLDC_SIXSTEP_HALLU_GPIO, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = BLDC_SIXSTEP_HALLV_PIN;
	GPIO_Init(BLDC_SIXSTEP_HALLV_GPIO, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = BLDC_SIXSTEP_HALLW_PIN;
	GPIO_Init(BLDC_SIXSTEP_HALLW_GPIO, &GPIO_InitStructure);	

	GPIO_InitStructure.GPIO_Pin = BLDC_SIXSTEP_FAULT_PIN;
	GPIO_Init(BLDC_SIXSTEP_FAULT_GPIO, &GPIO_InitStructure);	
	
	GPIO_ResetBits(BLDC_SIXSTEP_HALLU_GPIO, BLDC_SIXSTEP_HALLU_PIN);
	GPIO_ResetBits(BLDC_SIXSTEP_HALLV_GPIO, BLDC_SIXSTEP_HALLV_PIN);
	GPIO_ResetBits(BLDC_SIXSTEP_HALLW_GPIO, BLDC_SIXSTEP_HALLW_PIN);
	GPIO_ResetBits(BLDC_SIXSTEP_FAULT_GPIO, BLDC_SIXSTEP_FAULT_PIN);

	// Connect EXTI0 Line to PA.00 pin
	GPIO_EXTILineConfig(BLDC_SIXSTEP_HALLU_PORT_SOURCE, BLDC_SIXSTEP_HALLU_PIN_SOURCE);  
	// Configure EXTI Line
	EXTI_InitStructure.EXTI_Line = BLDC_SIXSTEP_HALLU_LINE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	
	NVIC_EnableIRQ(BLDC_SIXSTEP_HALLU_IRQn);	
	
	// Connect EXTI0 Line to PA.00 pin
	GPIO_EXTILineConfig(BLDC_SIXSTEP_HALLV_PORT_SOURCE, BLDC_SIXSTEP_HALLV_PIN_SOURCE);  
	// Configure EXTI Line
	EXTI_InitStructure.EXTI_Line = BLDC_SIXSTEP_HALLV_LINE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	
	NVIC_EnableIRQ(BLDC_SIXSTEP_HALLV_IRQn);	

	// Connect EXTI0 Line to PA.00 pin
	GPIO_EXTILineConfig(BLDC_SIXSTEP_HALLW_PORT_SOURCE, BLDC_SIXSTEP_HALLW_PIN_SOURCE);  
	// Configure EXTI Line
	EXTI_InitStructure.EXTI_Line = BLDC_SIXSTEP_HALLW_LINE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	
	NVIC_EnableIRQ(BLDC_SIXSTEP_HALLW_IRQn);

	// Connect EXTI0 Line to PA.00 pin
	GPIO_EXTILineConfig(BLDC_SIXSTEP_FAULT_PORT_SOURCE, BLDC_SIXSTEP_FAULT_PIN_SOURCE);  
	// Configure EXTI Line
	EXTI_InitStructure.EXTI_Line = BLDC_SIXSTEP_FAULT_LINE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	
	NVIC_EnableIRQ(BLDC_SIXSTEP_FAULT_IRQn);
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
u8 BLDC_SIXSTEP_Get_SpeedReachFlag(void)
{
	return BLDC_SIXSTEP_SpeedReachFlag;
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_Start(void)
{
	u8 hallstate;
	
	BLDC_SIXSTEP_RunFlag = 1;
//	BLDC_SIXSTEP_ExpectDuty = BLDC_SIXSTEP_INIT_DUTY;
//	BLDC_SIXSTEP_Duty = BLDC_SIXSTEP_INIT_DUTY;
//	BLDC_SIXSTEP_OriginalDuty = BLDC_SIXSTEP_INIT_DUTY;
	BLDC_SIXSTEP_ErrLast = 0;
	BLDC_SIXSTEP_RunCnt = 0;
	BLDC_SIXSTEP_SpeedReachFlag = 0;
	
	hallstate = BLDC_SIXSTEP_ReadHall();
	BLDC_SIXSTEP_HallSwitch(hallstate, BLDC_SIXSTEP_Duty);	
	
	ERR_BLDC_Clear();
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_StartMotor(void)
{
	BLDC_SIXSTEP_Start();
	
	BLDC_SIXSTEP_ExpectDuty = BLDC_SIXSTEP_INIT_DUTY;
	BLDC_SIXSTEP_Duty = BLDC_SIXSTEP_INIT_DUTY;
	BLDC_SIXSTEP_OriginalDuty = BLDC_SIXSTEP_INIT_DUTY;

}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_StopMotor(void)
{
	BLDC_SIXSTEP_RunFlag = 0;
	BLDC_SIXSTEP_ExpectDuty = 0;
	BLDC_SIXSTEP_Duty = 0;
	BLDC_SIXSTEP_ErrLast = 0;
	BLDC_SIXSTEP_RunCnt = 0;
	BLDC_SIXSTEP_SpeedReachFlag = 0;
	
	PWM_BLDC_SetWidth(1, 0);
	PWM_BLDC_SetWidth(2, 0);
	PWM_BLDC_SetWidth(3, 0);  
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
//u8 bldc_buff[100];
//u8 bldc_cnt=0;
void BLDC_SIXSTEP_HallSwitch(uint8_t hall_state, s16 duty)
{
//	bldc_buff[bldc_cnt] = hall_state;
//	bldc_cnt++;
//	if (bldc_cnt >= 100)
//		bldc_cnt = 0;
	switch(hall_state)
	{
		case 0x02: //AB
			GPIO_ResetBits(BLDC_SIXSTEP_LIN1_GPIO, BLDC_SIXSTEP_LIN1_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN2_GPIO, BLDC_SIXSTEP_LIN2_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN3_GPIO, BLDC_SIXSTEP_LIN3_PIN);
			SUP_Delay100us();
			PWM_BLDC_SetWidth(1, duty);
			PWM_BLDC_Stop(2);        
			PWM_BLDC_Stop(3); 
			GPIO_SetBits(BLDC_SIXSTEP_LIN2_GPIO, BLDC_SIXSTEP_LIN2_PIN); 
			break;
		
		case 0x06: //AC 	
			GPIO_ResetBits(BLDC_SIXSTEP_LIN1_GPIO, BLDC_SIXSTEP_LIN1_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN2_GPIO, BLDC_SIXSTEP_LIN2_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN3_GPIO, BLDC_SIXSTEP_LIN3_PIN);
			SUP_Delay100us();
			PWM_BLDC_SetWidth(1, duty);
			PWM_BLDC_Stop(2);        
			PWM_BLDC_Stop(3); 
			GPIO_SetBits(BLDC_SIXSTEP_LIN3_GPIO, BLDC_SIXSTEP_LIN3_PIN);
			break;
		
		case 0x04://BC		
			GPIO_ResetBits(BLDC_SIXSTEP_LIN1_GPIO, BLDC_SIXSTEP_LIN1_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN2_GPIO, BLDC_SIXSTEP_LIN2_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN3_GPIO, BLDC_SIXSTEP_LIN3_PIN);
			SUP_Delay100us();
			PWM_BLDC_Stop(1); 
			PWM_BLDC_SetWidth(2, duty);		
			PWM_BLDC_Stop(3); 
			GPIO_SetBits(BLDC_SIXSTEP_LIN3_GPIO, BLDC_SIXSTEP_LIN3_PIN); 		
			break;
		
		case 0x05://BA 	
			GPIO_ResetBits(BLDC_SIXSTEP_LIN1_GPIO, BLDC_SIXSTEP_LIN1_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN2_GPIO, BLDC_SIXSTEP_LIN2_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN3_GPIO, BLDC_SIXSTEP_LIN3_PIN);	
			SUP_Delay100us();
			PWM_BLDC_Stop(1); 
			PWM_BLDC_SetWidth(2, duty);		
			PWM_BLDC_Stop(3); 
			GPIO_SetBits(BLDC_SIXSTEP_LIN1_GPIO, BLDC_SIXSTEP_LIN1_PIN); 		
			break;
		
		case 0x01://CA
			GPIO_ResetBits(BLDC_SIXSTEP_LIN1_GPIO, BLDC_SIXSTEP_LIN1_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN2_GPIO, BLDC_SIXSTEP_LIN2_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN3_GPIO, BLDC_SIXSTEP_LIN3_PIN);
			SUP_Delay100us();
			PWM_BLDC_Stop(1);        
			PWM_BLDC_Stop(2);
			PWM_BLDC_SetWidth(3, duty);       
			GPIO_SetBits(BLDC_SIXSTEP_LIN1_GPIO, BLDC_SIXSTEP_LIN1_PIN); 
			break;
		
		case 0x03: //CB	
			GPIO_ResetBits(BLDC_SIXSTEP_LIN1_GPIO, BLDC_SIXSTEP_LIN1_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN2_GPIO, BLDC_SIXSTEP_LIN2_PIN); 
			GPIO_ResetBits(BLDC_SIXSTEP_LIN3_GPIO, BLDC_SIXSTEP_LIN3_PIN);	
			SUP_Delay100us();
			PWM_BLDC_Stop(1);        
			PWM_BLDC_Stop(2);
			PWM_BLDC_SetWidth(3, duty);    
			GPIO_SetBits(BLDC_SIXSTEP_LIN2_GPIO, BLDC_SIXSTEP_LIN2_PIN); 
			break;

		default:
			break;
	}
}


/**********************************************************************
* @Fuctionname   : 无刷电机获取霍尔信号
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
u8 BLDC_SIXSTEP_ReadHall(void)
{
	u8 State;
	
	State = 0;
	if(	GPIO_ReadInputDataBit(BLDC_SIXSTEP_HALLU_GPIO, BLDC_SIXSTEP_HALLU_PIN) != 0)
	{
		State |= 0x01;
	}
	if(	GPIO_ReadInputDataBit(BLDC_SIXSTEP_HALLV_GPIO, BLDC_SIXSTEP_HALLV_PIN) != 0)
	{
		State |= 0x02;
	}	
	if(	GPIO_ReadInputDataBit(BLDC_SIXSTEP_HALLW_GPIO, BLDC_SIXSTEP_HALLW_PIN) != 0)
	{
		State |= 0x04;
	}
	
	return State;
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_ClearParam(void)
{
	BLDC_SIXSTEP_SpeedCnt = 0;
	BLDC_SIXSTEP_PIDTime = 0;
	BLDC_SIXSTEP_ErrSum = BLDC_SIXSTEP_ExpectSpeed * 20;
	BLDC_SIXSTEP_ErrLast = 0;
	
	BLDC_SIXSTEP_SpeedReachFlag = 0;
	
	ERR_BLDC_Clear();
}


u8 hallstate2[6];
/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_Config(void)
{
	u8 i;
	
	BLDC_SIXSTEP_Duty = 0;
	BLDC_SIXSTEP_HallCnt = 0;
	BLDC_SIXSTEP_ExpectSpeed = Speed.Speed_set;		//电机目标速度
	BLDC_SIXSTEP_RunFlag = 0;	
	BLDC_SIXSTEP_Direction = 0;
	BLDC_SIXSTEP_SpeedTime = 0;
	BLDC_SIXSTEP_RunTime = 0;
	BLDC_SIXSTEP_PIDTime = 0;
	BLDC_SIXSTEP_ErrDetectTime = 0;
	BLDC_SIXSTEP_ErrLast = 0;
	BLDC_SIXSTEP_ErrSum = 0;
	BLDC_SIXSTEP_SpeedReachFlag = 0;
	BLDC_SIXSTEP_IntLastStatus = 0;
	BLDC_SIXSTEP_RunCnt = 0;
	BLDC_SIXSTEP_CurrentTime = 0;
	
	BLDC_SIXSTEP_SpeedCnt = 0;
	memset(BLDC_SIXSTEP_SpeedCnt_Buff, 0, BLDC_SIXSTEP_SPEED_CALA_CNT * sizeof(u32));	
	memset(BLDC_SIXSTEP_SpeedTime_Buff, 0, BLDC_SIXSTEP_SPEED_CALA_CNT * sizeof(s64));	

	BLDC_SIXSTEP_CHN_GPIO_Config();
	BLDC_SIXSTEP_HALL_GPIO_Config();
	BLDC_SIXSTEP_StopMotor();	
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_SetDuty(s16 duty)
{
	BLDC_SIXSTEP_Duty = duty;
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_SetDirection(u8 direction)
{
	s64 tim, timtemp;
	u8 i;
	
	if (BLDC_SIXSTEP_Direction != direction)
	{
		// 清除速度计算缓存
		for (i=0; i<BLDC_SIXSTEP_SPEED_CALA_CNT; i++)
		{
			BLDC_SIXSTEP_SpeedCnt_Buff[i] = BLDC_SIXSTEP_HallCnt;
		}
		BLDC_SIXSTEP_RealSpeed = 0;
		
		// 如果处于运行状态, 则先停止20ms再启动反转
		if (BLDC_SIXSTEP_RunFlag != 0)
		{		
			BLDC_SIXSTEP_StopMotor();
			timtemp = SYSTICK_GetTime();
			BLDC_SIXSTEP_HallUpdateFlag = 0;
			while (1)
			{
				tim = SYSTICK_GetTime();
				if ((tim - timtemp) > 100000)
				{
					timtemp = tim;
					if (BLDC_SIXSTEP_HallUpdateFlag == 0)
					{
						break;
					}
					else
					{
						BLDC_SIXSTEP_HallUpdateFlag = 0;
					}
				}
			}
			BLDC_SIXSTEP_Start();
		}
		BLDC_SIXSTEP_Direction = direction;
	}
	
	if (BLDC_SIXSTEP_RunFlag == 0)
	{
		BLDC_SIXSTEP_Duty = 0;
		BLDC_SIXSTEP_ExpectDuty = 0;
	}
	else
	{
		// 通过判断过冲最大速度计算启动占空比
		if (BLDC_SIXSTEP_MaxSpeed >= (BLDC_SIXSTEP_ExpectSpeed + 2 * BLDC_SIXSTEP_SPEED_BIAS))
		{
			if (BLDC_SIXSTEP_OriginalDuty < (((BLDC_SIXSTEP_MaxSpeed - BLDC_SIXSTEP_ExpectSpeed) *5) + BLDC_SIXSTEP_INIT_DUTY))
			{
				BLDC_SIXSTEP_OriginalDuty = BLDC_SIXSTEP_INIT_DUTY;
			}
			else
			{
				BLDC_SIXSTEP_OriginalDuty -= (BLDC_SIXSTEP_MaxSpeed - BLDC_SIXSTEP_ExpectSpeed) * 5;
			}
			BLDC_SIXSTEP_MaxSpeed = BLDC_SIXSTEP_ExpectSpeed;
		}		
		BLDC_SIXSTEP_Duty = BLDC_SIXSTEP_OriginalDuty;
		BLDC_SIXSTEP_ExpectDuty = BLDC_SIXSTEP_OriginalDuty;
	}	
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_Foreward(void)
{
	BLDC_SIXSTEP_ClearParam();
	BLDC_SIXSTEP_SetDirection(0);
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_Reversal(void)
{
	BLDC_SIXSTEP_ClearParam();
	BLDC_SIXSTEP_SetDirection(1);	
}


/**********************************************************************
* @Fuctionname   : 无刷电机速度设置
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_SetSpeed(s16 speed)
{
	BLDC_SIXSTEP_MaxSpeed = BLDC_SIXSTEP_ExpectSpeed;
	BLDC_SIXSTEP_OriginalDuty = BLDC_SIXSTEP_INIT_DUTY;
	
	BLDC_SIXSTEP_ClearParam();
	BLDC_SIXSTEP_ExpectSpeed = speed;
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
s16 BLDC_SIXSTEP_GetSpeed(void)
{
	s16 speed;
	
	if ((BLDC_SIXSTEP_RealSpeed >= (BLDC_SIXSTEP_ExpectSpeed - BLDC_SIXSTEP_SPEED_BIAS)) && (BLDC_SIXSTEP_RealSpeed <= (BLDC_SIXSTEP_ExpectSpeed + 2 * BLDC_SIXSTEP_SPEED_BIAS)))
	{
		speed = BLDC_SIXSTEP_ExpectSpeed;
	}
	else
	{
		if(CrossDisTimer.Pcntr>200)
			speed = BLDC_SIXSTEP_ExpectSpeed;		//显示目标速度
		else
			speed = BLDC_SIXSTEP_RealSpeed;			//显示真实速度
	}
	return speed;	
}


/**********************************************************************
* @Fuctionname   : 计算无刷电机的速度
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_CalaSpeed(s64 tim)
{
	u8 i;
	u32 speed_cnt;
	u32 speed_tim_ms;
	
	if ((tim - BLDC_SIXSTEP_SpeedTime) > BLDC_SIXSTEP_SPEED_PERIOD)
	{
		BLDC_SIXSTEP_SpeedTime = tim;
													 		
		memmove(BLDC_SIXSTEP_SpeedCnt_Buff, BLDC_SIXSTEP_SpeedCnt_Buff + 1, (BLDC_SIXSTEP_SPEED_CALA_CNT - 1) * sizeof(u32));
		memmove(BLDC_SIXSTEP_SpeedTime_Buff, BLDC_SIXSTEP_SpeedTime_Buff + 1, (BLDC_SIXSTEP_SPEED_CALA_CNT - 1) * sizeof(s64));

		BLDC_SIXSTEP_SpeedCnt_Buff[BLDC_SIXSTEP_SPEED_CALA_CNT - 1] = BLDC_SIXSTEP_HallCnt;
		BLDC_SIXSTEP_SpeedTime_Buff[BLDC_SIXSTEP_SPEED_CALA_CNT - 1] = tim;
				
		speed_cnt = BLDC_SIXSTEP_SpeedCnt_Buff[BLDC_SIXSTEP_SPEED_CALA_CNT - 1] - BLDC_SIXSTEP_SpeedCnt_Buff[0];
		speed_tim_ms = (BLDC_SIXSTEP_SpeedTime_Buff[BLDC_SIXSTEP_SPEED_CALA_CNT - 1] - BLDC_SIXSTEP_SpeedTime_Buff[0]) / 1000;
		
		BLDC_SIXSTEP_RealSpeed = speed_cnt * 60000 / speed_tim_ms / BLDC_SIXSTEP_ENCODER_ONE_CYCLE_NUM;			
	}
}

/**********************************************************************
* @Fuctionname   : 计算无刷电机的电流
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
float ccc;
void BLDC_SIXSTEP_CalaCurrent(s64 tim)
{
	u8 i;
	u32 sum;
	
	if ((tim - BLDC_SIXSTEP_CurrentTime) > BLDC_SIXSTEP_CURRENT_TIME)
	{
		BLDC_SIXSTEP_CurrentTime = tim;
													 		
		ccc = PADC_GetVol();		
	}
}


/**********************************************************************
* @Fuctionname   : 无刷电机换相
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_PhaseChange(void)
{
	u8 hallstate;
							   
	hallstate = BLDC_SIXSTEP_ReadHall();
	if (BLDC_SIXSTEP_Direction != 0)
	{
		hallstate = 7 - hallstate;
	}
	BLDC_SIXSTEP_HallSwitch(hallstate, BLDC_SIXSTEP_Duty);
}

s32 pp, pi, pd;
s32 duty;

/**********************************************************************
* @Fuctionname   : 无刷电机速度PID
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_SpeedPidCtrl(s64 tim)
{
	s16 err;
//	u8 hallstate;
//	s32 duty;
	 
	if ((tim - BLDC_SIXSTEP_PIDTime) > BLDC_SIXSTEP_SPEED_PERIOD)
	{
		BLDC_SIXSTEP_PIDTime = tim;
		BLDC_SIXSTEP_RunTime = 0;
		
		// 计算电机启动的原始占空比, 适配不同的负载
		if ((BLDC_SIXSTEP_RealSpeed > 2) && (BLDC_SIXSTEP_RealSpeed < 10))
		{
			BLDC_SIXSTEP_OriginalDuty = BLDC_SIXSTEP_Duty;
		}
		
		if (BLDC_SIXSTEP_RealSpeed > BLDC_SIXSTEP_MaxSpeed)
		{
			BLDC_SIXSTEP_MaxSpeed = BLDC_SIXSTEP_RealSpeed;
		}
		
		
		
		err = BLDC_SIXSTEP_ExpectSpeed - BLDC_SIXSTEP_RealSpeed;				
		if (abs(err) < BLDC_SIXSTEP_SPEED_BIAS)
		{
			if (BLDC_SIXSTEP_SpeedReachFlag == 0)
			{
				
				BLDC_SIXSTEP_SpeedReachFlag = 1;
			}
		}
		
		// 计数加一
		if (BLDC_SIXSTEP_RunCnt < BLDC_SIXSTEP_SPEED_BUFF_CNT)
		{
			BLDC_SIXSTEP_RunCnt ++;
		}
		else
		{
			BLDC_SIXSTEP_RunCnt = 0;
		}
		
		// 1秒运行一次, 计算目标duty
		if (BLDC_SIXSTEP_RunCnt == 0)
		{			
			if (err > 0)
			{
				if (err > 20)
				{
					duty = err / 2;
					if (duty < 10)
					{
						duty = 10;
					}
				}
				else
				{
					duty = err;
				}
			}
			else
			{
				if (err < -20)
				{
					duty = err / 2;
					if (duty > -10)
					{
						duty = -10;
					}					
				}
				else
				{
					duty = err;
				}				
			}

			// 限制duty
			if (duty > 300)
			{
				duty = 300;
			}
			else if (duty < -500)
			{
				duty = -500;
			}
			// 计算目标duty
			if ((BLDC_SIXSTEP_ExpectDuty + duty) > (PWM_BLDC_PERIOD - 20))
			{
				BLDC_SIXSTEP_ExpectDuty = PWM_BLDC_PERIOD - 20;
			}
			else if ((BLDC_SIXSTEP_ExpectDuty + duty) < BLDC_SIXSTEP_INIT_DUTY)
			{
				BLDC_SIXSTEP_ExpectDuty = BLDC_SIXSTEP_INIT_DUTY;
			}	
			else
			{
				BLDC_SIXSTEP_ExpectDuty += duty;
			}
		}
		
		// 100毫秒运行一次, 计算运行duty
		if (BLDC_SIXSTEP_Duty < BLDC_SIXSTEP_ExpectDuty)
		{
			BLDC_SIXSTEP_Duty += 2000 / BLDC_SIXSTEP_SPEED_BUFF_CNT;
			if (BLDC_SIXSTEP_Duty > BLDC_SIXSTEP_ExpectDuty)
			{
				BLDC_SIXSTEP_Duty = BLDC_SIXSTEP_ExpectDuty;
			}
			else
			{
				BLDC_SIXSTEP_ExpectDuty = BLDC_SIXSTEP_Duty;
			}			
		}
		else if (BLDC_SIXSTEP_Duty > BLDC_SIXSTEP_ExpectDuty)
		{
			BLDC_SIXSTEP_Duty -= 2000 / BLDC_SIXSTEP_SPEED_BUFF_CNT;
			if (BLDC_SIXSTEP_Duty < BLDC_SIXSTEP_ExpectDuty)
			{
				BLDC_SIXSTEP_Duty = BLDC_SIXSTEP_ExpectDuty;
			}
			else
			{
				BLDC_SIXSTEP_ExpectDuty = BLDC_SIXSTEP_Duty;
			}			
		}
		
		// 如果hall没有中断即电机堵转, 手动换向增加duty加大输出力矩
		if (BLDC_SIXSTEP_HallUpdateFlag == 0)
		{
			BLDC_SIXSTEP_PhaseChange();
		}
		BLDC_SIXSTEP_HallUpdateFlag = 0;		
	}	
}


/**********************************************************************
* @Fuctionname   : 无刷电机错误检测
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_MotorErrDetect(s64 tim)
{
	u8 cnt;

	if ((tim - BLDC_SIXSTEP_ErrDetectTime) > BLDC_SIXSTEP_SPEED_SAMPLE_TIME)
	{
		BLDC_SIXSTEP_ErrDetectTime = tim;
		
		if ((BLDC_SIXSTEP_RealSpeed < 10) && (BLDC_SIXSTEP_Duty > (BLDC_SIXSTEP_MAX_DUTY - 200)))
		{		
			ERR_BLDC_Stop_Proc();
		}
		else if ((BLDC_SIXSTEP_RealSpeed + 50)< BLDC_SIXSTEP_ExpectSpeed)
		{
			if (BLDC_SIXSTEP_SpeedReachFlag == 1)
			{
				ERR_BLDC_BelowMin_Proc();
			}
		}
		else if (BLDC_SIXSTEP_RealSpeed > (BLDC_SIXSTEP_ExpectSpeed + 50))
		{
			if (BLDC_SIXSTEP_SpeedReachFlag == 1)
			{
				ERR_BLDC_AboveMax_Proc();
			}		
		}
		else
		{
			ERR_BLDC_Clear();		
		}
	}
}


u8 hallstate1;
/**********************************************************************
* @Fuctionname   : 无刷电机运行处理函数
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_Proc(void)
{
	s64 tim;
	
	tim = SYSTICK_GetTime();
	
	BLDC_SIXSTEP_CalaSpeed(tim);
	BLDC_SIXSTEP_CalaCurrent(tim);
	
	if (BLDC_SIXSTEP_RunFlag != 0)
	{
		BLDC_SIXSTEP_SpeedPidCtrl(tim);
		
		// motor error 
		BLDC_SIXSTEP_MotorErrDetect(tim);		
	}
	
	hallstate1 = BLDC_SIXSTEP_ReadHall();
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_IntProc(void)
{	
	if (GPIO_ReadInputDataBit(BLDC_SIXSTEP_HALLU_GPIO, BLDC_SIXSTEP_HALLU_PIN) == 0)
	{
		if (BLDC_SIXSTEP_IntLastStatus == 1)
		{
			// 上升沿计数
			BLDC_SIXSTEP_SpeedCnt++;
			BLDC_SIXSTEP_IntLastStatus = 0;
		}
	}
	else
	{
		BLDC_SIXSTEP_IntLastStatus = 1;
	}
}


/**********************************************************************
* @Fuctionname   : 霍尔中断线回调函数
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void HAL_GPIO_EXTI_Callback(void)  //霍尔中断线回调函数
{ 			
	BLDC_SIXSTEP_PhaseChange();
		
//	BLDC_SIXSTEP_HallCnt++;
	++BLDC_SIXSTEP_HallCnt;
	BLDC_SIXSTEP_HallUpdateFlag = 1;
}

u32 u_cnt=0;
u32 v_cnt=0;
u32 w_cnt=0;

/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_HALLU_IRQHandler(void)
{
	if(EXTI_GetITStatus(BLDC_SIXSTEP_HALLU_LINE) != RESET)
	{
		HAL_GPIO_EXTI_Callback();
		BLDC_SIXSTEP_SpeedCnt++;
		u_cnt++;
		/* Clear the  EXTI line 0 pending bit */
		EXTI_ClearITPendingBit(BLDC_SIXSTEP_HALLU_LINE);
	}

	if(EXTI_GetITStatus(BLDC_SIXSTEP_HALLW_LINE) != RESET)
	{
		HAL_GPIO_EXTI_Callback();
		w_cnt++;
		/* Clear the  EXTI line 0 pending bit */
		EXTI_ClearITPendingBit(BLDC_SIXSTEP_HALLW_LINE);
	}	
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_HALLV_IRQHandler(void)
{
	if(EXTI_GetITStatus(BLDC_SIXSTEP_HALLV_LINE) != RESET)
	{
		HAL_GPIO_EXTI_Callback();
		v_cnt++;
		/* Clear the  EXTI line 0 pending bit */
		EXTI_ClearITPendingBit(BLDC_SIXSTEP_HALLV_LINE);
	}	
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
//void BLDC_SIXSTEP_HALLW_IRQHandler(void)
//{
//	if(EXTI_GetITStatus(BLDC_SIXSTEP_HALLW_LINE) != RESET)
//	{
//		HAL_GPIO_EXTI_Callback();
//		w_cnt++;
//		/* Clear the  EXTI line 0 pending bit */
//		EXTI_ClearITPendingBit(BLDC_SIXSTEP_HALLW_LINE);
//	}	
//}


void Delay_us(unsigned long int cnt)

 { unsigned char i;
   while(cnt--)
   {
   	for(i=0;i<5;i++);
   } 
 }
 
/**********************************************************************
* @Fuctionname   : 无刷电机故障
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void BLDC_SIXSTEP_FAULT_IRQHandler(void)
{
	if(EXTI_GetITStatus(BLDC_SIXSTEP_FAULT_LINE) != RESET)
	{
		Delay_us(10);
		if(	GPIO_ReadInputDataBit(BLDC_SIXSTEP_FAULT_GPIO, BLDC_SIXSTEP_FAULT_PIN) == 0)
		{
			ERR_BLDC_OverCurrent_Proc();
		}
		/* Clear the  EXTI line 0 pending bit */
		EXTI_ClearITPendingBit(BLDC_SIXSTEP_FAULT_LINE);
	}	
}

/*********************************  COPYRIGHT 2022 --------  *********  END OF FILE  **********************************/
